package com.jfs.qy.config.component;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jfs.qy.config.DirectRabbitConfig;
import com.jfs.qy.constant.GlobalConstant;
import com.jfs.qy.entity.MqAlarmMessage;
import com.jfs.qy.entity.ObjectInfo;
import com.jfs.qy.entity.request.SearchAlarmRtspUrlRequest;
import com.jfs.qy.entity.request.SearchAlarmRtspUrlRequestData;
import com.jfs.qy.entity.response.SearchAlarmRtspUrlResponse;
import com.jfs.qy.enums.StreamModEnum;

import com.jfs.qy.enums.TransportTypeEnum;
import com.jfs.qy.service.SystemSearchAlarmRtspUrlService;
import com.jfs.qy.template.S3Template;
import com.jfs.qy.utils.JavaCVRecordUtil;
import com.jfs.qy.utils.SystemCommonUtils;
import com.jfs.qy.utils.UrlParameterUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import java.io.File;
import java.nio.file.Files;
import java.util.Date;
import java.util.Objects;

/**
 * @Description 处理告警事件线程任务
 * @E-mail cwm3412638@163.com
 * @Author cwm
 * @Date 2022/11/5
 */
@Slf4j
public class ProcessAlarmTask  implements Runnable{
    private final SystemSearchAlarmRtspUrlService systemSearchAlarmRtspUrlService;
    private final SystemCommonUtils systemCommonUtils;
    private final S3Template s3Template;
    private final RabbitTemplate rabbitTemplate;

    public ProcessAlarmTask(SystemSearchAlarmRtspUrlService systemSearchAlarmRtspUrlService, SystemCommonUtils systemCommonUtils, S3Template s3Template, RabbitTemplate rabbitTemplate) {
        this.systemSearchAlarmRtspUrlService = systemSearchAlarmRtspUrlService;
        this.systemCommonUtils = systemCommonUtils;
        this.s3Template = s3Template;
        this.rabbitTemplate = rabbitTemplate;
    }

    @Override
    public void run() {
        File file = null;
        File imageFile = null;
        try {
            //从队列中取出告警事件
            AlarmEvent alarmEvent = AlarmEventBlockQueue.get();
            if (Objects.isNull(alarmEvent)) {
                return;
            }
            //根据事件查询事件播放url
            //构建请求对象
            SearchAlarmRtspUrlRequest searchAlarmRtspUrlRequest = new SearchAlarmRtspUrlRequest();
            SearchAlarmRtspUrlRequestData.Builder builder = new SearchAlarmRtspUrlRequestData.Builder()
                    .channel(alarmEvent.getChannelName())
                    .transportType(TransportTypeEnum.UDP.getValue())
                    .streamMod(StreamModEnum.SUBSTREAM.getValue());
            //计算时间
            //产生告警的时间
            String time = alarmEvent.getTime();
            //UTC时间  = 当前时间 -8小时
            DateTime parse = DateUtil.parse(time, DatePattern.NORM_DATETIME_PATTERN);
            long utc = parse.getTime() - (1000 * 60 * 60 * 8);
            DateTime utcDate = DateUtil.date(utc);
            String year = DateUtil.format(utcDate, DatePattern.NORM_DATE_PATTERN);
            //设置开始 结束时间
            String startTime = DateUtil.format(DateUtil.date(utc - systemCommonUtils.getRecordAlarmTime()), DatePattern.NORM_TIME_PATTERN);
            String endTime = DateUtil.format(DateUtil.date(utc + systemCommonUtils.getRecordAlarmTime()), DatePattern.NORM_TIME_PATTERN);
            if (log.isDebugEnabled()) {
                log.debug("查询告警视频播放url开始时间:{},结束时间:{}", startTime, endTime);
            }
            SearchAlarmRtspUrlRequestData data = builder.startDate(year)
                    .endDate(year)
                    .startTime(startTime)
                    .endTime(endTime)
                    .recordType(4294967295L)
                    .build();
            searchAlarmRtspUrlRequest.setData(data);
            //发送请求
            ResponseEntity<SearchAlarmRtspUrlResponse> searchAlarmRtspUrlResponseResponseEntity = systemSearchAlarmRtspUrlService.searchPlaybackRtspUrl(searchAlarmRtspUrlRequest);
            if (Objects.nonNull(searchAlarmRtspUrlResponseResponseEntity) && HttpStatus.OK.equals(searchAlarmRtspUrlResponseResponseEntity.getStatusCode())) {
                if (log.isDebugEnabled()) {
                    log.debug("查询到告警事件的视频rtsp播放地址:{}", JSONUtil.toJsonStr(searchAlarmRtspUrlResponseResponseEntity));
                }
                String playbackUrl = Objects.requireNonNull(searchAlarmRtspUrlResponseResponseEntity.getBody()).getData().getPlaybackUrl();
                if (StrUtil.isNotEmpty(playbackUrl)) {
                    //录制视频
                    //生成视频文件名 告警事件-告警通道名称-告警通道Ip地址-告警类型
                    String fileName = DateUtil.format(DateUtil.parse(time, DatePattern.NORM_DATETIME_PATTERN), DatePattern.CHINESE_DATE_TIME_PATTERN)
                            + GlobalConstant.BAR + alarmEvent.getChannelName()
                            + GlobalConstant.BAR + alarmEvent.getIp()
                            + GlobalConstant.BAR + alarmEvent.getName() + GlobalConstant.VEDIO_PERFIX_NAME;
                    String outputFile = systemCommonUtils.getTemporaryVideoStoragePath() + GlobalConstant.FIL_DIRECTORY_PREFIX + fileName;
                    //生成视频封面图片名称 告警事件-告警通道名称-告警通道Ip地址-告警类型
                    final String imageName = DateUtil.format(DateUtil.parse(time, DatePattern.NORM_DATETIME_PATTERN), DatePattern.CHINESE_DATE_TIME_PATTERN)
                            + GlobalConstant.BAR + alarmEvent.getChannelName() + GlobalConstant.BAR +
                            alarmEvent.getIp() + GlobalConstant.BAR + alarmEvent.getName() + GlobalConstant.SOPT + ImgUtil.IMAGE_TYPE_JPG;
                    //拼接图片输出临时地址
                    final String imageOutPath = systemCommonUtils.getTemporaryImageStoragePath() + GlobalConstant.FIL_DIRECTORY_PREFIX + imageName;
                    String startTime1 = UrlParameterUtils.getParamByUrl(playbackUrl, "starttime");
                    String endTime1 = UrlParameterUtils.getParamByUrl(playbackUrl, "endtime");
                    Date startDateTime = DateUtil.parseUTC(startTime1);
                    Date endDateTime = DateUtil.parseUTC(endTime1);
                    JavaCVRecordUtil.frameRecord(playbackUrl, outputFile, 1, (endDateTime.getTime() - startDateTime.getTime()));
                    //录制完毕后上传对象到对象存储服务器
                    file = new File(outputFile);
                    if (file.exists()) {
                        ObjectInfo videoObjectInfo = s3Template.upload(fileName, Files.newInputStream(file.toPath()));
                        //截取视频第一帧作为封面图片
                        JavaCVRecordUtil.getImage(outputFile, imageOutPath);
                        imageFile = new File(imageOutPath);
                        if (imageFile.exists()) {
                            ObjectInfo imageObjectInfo = s3Template.upload(systemCommonUtils.getCoverBucketName(), imageName, Files.newInputStream(imageFile.toPath()));
                            //发布事件到消息队列中
                            //构建消息事件对象
                            if (Objects.nonNull(videoObjectInfo) && Objects.nonNull(imageObjectInfo) && StrUtil.isNotEmpty(videoObjectInfo.getObjectUrl()) && StrUtil.isNotEmpty(imageObjectInfo.getObjectUrl())) {
                                MqAlarmMessage message = new MqAlarmMessage.Builder()
                                        .name(alarmEvent.getName())
                                        .channelName(alarmEvent.getChannelName())
                                        .ip(alarmEvent.getIp())
                                        .time(DateUtil.now())
                                        .videoPath(videoObjectInfo.getObjectUrl())
                                        .imagePath(imageObjectInfo.getObjectUrl())
                                        .type(alarmEvent.getType())
                                        .build();
                                //发送消息
                                if (log.isDebugEnabled()) {
                                    log.debug("发送告警事件消息到rabbitmq中:{}", JSONUtil.toJsonStr(message));
                                }
                                rabbitTemplate.convertAndSend(DirectRabbitConfig.Direct_EXCHANGE_NAME, DirectRabbitConfig.DIRECT_ROUTING_KEY, JSONUtil.toJsonStr(message));
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //删除临时文件
            if (file != null && file.exists()) {
                file.delete();
            }
            if (imageFile != null && imageFile.exists()) {
                imageFile.delete();
            }
        }
    }
}
